/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "MBT_Engine.h"


#include <future>
using namespace std;



//S_板载缓存* S_Engine::m_预设几何索引 = nullptr;
static S_Mesh* g预设图形网格 = nullptr;

S_UI创建环境*  S_Engine::m_UIctx = nullptr;
bool           S_Engine::m_资源加载线程 = true;
bool           S_Engine::g_渲染线程 = true;
atomic_int32_t S_Engine::g_在运行线程 = 0;

std::string    S_Engine::g_着色器文件路径;

map<uint64, S_Window*> S_Engine::g_窗口容器;




S_Engine::S_Engine() {
	m_绘图框架 = 0;
	m_UIctx = nullptr;

	
}

S_Engine::~S_Engine() {
	
}




void S_Engine::f_InitDX12() {
	m_绘图框架 = f_创建绘图框架(E_绘图API::E_DirectX12);
	m_API_Name = E_绘图API::E_DirectX12;
}

void S_Engine::f_InitVK() {
	S_UI创建环境::f_初始化预设图元();

	m_绘图框架 = f_创建绘图框架(E_绘图API::E_Vulkan);
	m_API_Name = E_绘图API::E_Vulkan;

	uint32 num = m_绘图框架->m_设备.size();
	for (uint32 i = 0; i < num; ++i) {
		f_创建绘图设备(i);
	}

	S_引擎配置::f_初始化着色器文件路径();
}



S_设备 S_Engine::f_get设备(uint32 物理设备ID) {
	if (m_绘图框架) {
		return m_绘图框架->m_设备[物理设备ID];
	}
	return S_设备();
}

S_设备环境 S_Engine::f_get环境(uint32 物理设备ID, uint32 逻辑设备ID) {
	return { m_绘图框架->m_Type, m_绘图框架->m_设备[物理设备ID].物理设备, m_绘图框架->m_设备[物理设备ID].逻辑设备[0] };
}


S_设备		S_Engine::f_get光追设备() {
	uint32 num = m_绘图框架->m_设备.size();
	for (uint32 i = 0; i < num; ++i) {
		if (f_device_是否支持光追(m_绘图框架->m_设备[i])) {
			return m_绘图框架->m_设备[i];
		}
	}
	return S_设备();
}
S_设备环境	S_Engine::f_get光追设备环境(uint32 逻辑设备ID) {
	uint32 num = m_绘图框架->m_设备.size();
	for (uint32 i = 0; i < num; ++i) {
		if (f_device_是否支持光追(m_绘图框架->m_设备[i])) {
			return { m_绘图框架->m_Type, m_绘图框架->m_设备[i].物理设备, m_绘图框架->m_设备[i].逻辑设备[逻辑设备ID] };
		}
	}
	return {};
}

S_协处理设备 S_Engine::f_创建绘图设备(uint32 物理设备ID) {
	switch (m_API_Name)
	{
	case E_Vulkan: {
			auto phy = m_绘图框架->f_取物理设备(物理设备ID);
			auto dev = m_绘图框架->f_创建图形逻辑设备(phy, f_device_是否支持光追(phy));
			m_绘图框架->m_设备[物理设备ID].逻辑设备.push_back(dev);
			return dev;
		}
		
		break;
	case E_DirectX12:
		break;
	default:
		break;
	}

	return { 0 };
}

void S_Engine::f_Loop() {
	/*if (!m_绘图框架->m_是否暂停 && m_当前更新场景) {
		m_当前更新场景->f_Update();

		m_绘图框架->f_Begin(m_绘图框架->m_设备[0].逻辑设备[0]);
		m_当前更新场景->f_Render();
		m_绘图框架->f_End(m_绘图框架->m_设备[0].逻辑设备[0]);
	}*/
	
	//m_绘图框架->f_绘制(m_绘图框架->m_设备[0].逻辑设备[0]);
}

void S_Engine::f_asynLoop() {

}

void S_Engine::f_Close() {
	for (auto& e : C_Widget::G键位映射容器) {
		free(e);
	}
	C_Widget::G键位映射容器.clear();
}

void S_Engine::f_异步创建着色(std::vector<std::string>& name, int32 pyDev, int32 logDev) {
	if (m_API_Name == E_绘图API::E_Vulkan) {
		std::future<void> f1 = std::async(std::launch::async, [&]() {
			//m_绘图框架->f_创建着色器(name, 参数, pyDev, logDev);
		});
		f1.wait();
	}
	else {

	}
}

void S_Engine::f_初始化设备数据(S_设备环境& ctx, bool 启用光追) {
	uint32 Flags = E_板载缓存类型::e_INDEX;

	f_surface_初始化GPU内存(ctx);

	if (启用光追 && ctx.m_支持光追) {
		//g预设图形网格 = f_surface_创建网格对象(0, ctx, E_网格数据枚举::e_Mesh_VULKAN);
	}
	
	//================================= 物体数据初始化 ===================================
	S_物体::g_变换矩阵 = f_buf_create板载缓存(ctx, sizeof(Mat44f), E_板载缓存类型::e_SSBO);
	S_物体::g_物体属性 = f_buf_create板载缓存(ctx, sizeof(S_MeshTranformProp), E_板载缓存类型::e_SSBO);

	S_物体::g_骨骼长度 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, sizeof(float32));
	S_物体::g_姿态变换 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, sizeof(Mat44f));
	S_物体::g_骨骼变换 = f_buf_create板载缓存(ctx, E_板载缓存类型::e_SSBO, sizeof(Mat44f));

	S_物体::g_物体颜色.resize(8);
	for (uint32 i = 0; i < 8; ++i) {
		S_物体::g_物体颜色[i] = f_buf_create板载缓存(ctx, sizeof(uint32), E_板载缓存类型::e_SSBO);
	}
	

}

void S_Engine::f_释放线程数据() {
	m_资源加载线程 = false;
	g_渲染线程 = false;

	for (uint32 i = 0; i < 1000; ++i) {
		if (S_Engine::g_在运行线程 > 0) {
			std::this_thread::sleep_for(std::chrono::milliseconds(30));
		}
		else {
			break;
		}
	}
}

void S_Engine::f_释放设备数据() {
	f_surface_释放所有GPU内存();

	f_buf_release板载缓存(S_物体::g_变换矩阵);
	f_buf_release板载缓存(S_物体::g_物体属性);

	for (auto& e : S_物体::g_物体颜色) {
		f_buf_release板载缓存(e);
	}
	
	S_Engine::g_窗口容器.clear();
}


S_Mesh* S_Engine::f_get预设图形网格() {
	return g预设图形网格;
}

S_帧渲染层* f_create帧渲染层(C_Widget管理& gm, S_Scene* scene) {
	S_帧渲染层* rl = (S_帧渲染层*)malloc(sizeof(S_帧渲染层));

	rl->m_Scene = (S_结构对象指针)scene;

	auto* face = f_surface_Create(gm.m_UICtx->m_Ctx, { 1024, 576 });
	rl->m_Surface3D = (S_结构对象指针)face;

	f_tex_安装纹理采样器(face->m_Color[0], gm.m_UICtx->m_Mat->m_采样器);
	f_tex_安装纹理采样器(face->m_Color[1], gm.m_UICtx->m_Mat->m_采样器);
	f_tex_安装纹理采样器(face->m_Color[2], gm.m_UICtx->m_Mat->m_采样器);


	return rl;
}
